package com.pig4cloud.pigx.wallet.websocket.subscribe;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.websocket.holder.SessionKeyGenerator;
import com.pig4cloud.pigx.contract.api.feign.ContractPositionFeign;
import com.pig4cloud.pigx.wallet.entity.ContractAccount;
import com.pig4cloud.pigx.wallet.service.ContractAccountService;
import com.pig4cloud.pigx.wallet.vo.AbstractTopicVO;
import com.pig4cloud.pigx.wallet.websocket.ContractAccountVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 */
@Slf4j
@Component
public class ContractAccountHandler extends DataListAbstractTopic {

	private final ContractAccountService contractAccountService;

	private final SessionKeyGenerator sessionKeyGenerator;

	private final ContractPositionFeign feign;

	protected String TOPICNAME = "contractAccount";

	public ContractAccountHandler(ContractAccountService contractAccountService, SessionKeyGenerator sessionKeyGenerator, ContractPositionFeign feign) {
		this.contractAccountService = contractAccountService;
		this.sessionKeyGenerator = sessionKeyGenerator;
		this.feign = feign;
		init();
	}

	private void init() {
		wsPush();
	}


	private void wsPush() {
		ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
		service.scheduleAtFixedRate(() -> {
			try {
				for (Map.Entry<WebSocketSession, AbstractTopicVO> entry : subList.entrySet()) {

					if (entry.getKey().isOpen() == false) {
						continue;
					}
					try {
						Object userId = sessionKeyGenerator.sessionKey(entry.getKey());
						ContractAccountVo vo = new ContractAccountVo();
						ContractAccount contractAccount = contractAccountService.getOne(new LambdaQueryWrapper<ContractAccount>()
								.eq(ContractAccount::getUserId, userId));

						// 查询未实现盈亏，精度2
						R<BigDecimal> floatProfitR = feign.getFloatProfitByUser(Long.valueOf(userId.toString()), SecurityConstants.FROM_IN);
						BigDecimal floatProfit = floatProfitR.getIsSuccess() ? floatProfitR.getData() : BigDecimal.ZERO;

						try {
							// 精度4
							int scale = 4;
							// 向下取值
							RoundingMode mode = RoundingMode.DOWN;

							// 转换为BigDecimal，并设置精度，向下取值
							BigDecimal total = contractAccount.getMarginBalance().setScale(scale, mode);
							BigDecimal available = contractAccount.getWalletBalance().setScale(scale, mode);
							BigDecimal frozen = contractAccount.getFrozen().setScale(scale, mode);
							BigDecimal positionMargin = contractAccount.getPositionMargin().setScale(scale, mode);

							// 总资产
							vo.setTotal(total.add(floatProfit));
							// 可用额度
							vo.setAvailable(available);
							// 冻结额度
							vo.setFrozen(frozen);
							// （持仓保证金）占用额度
							vo.setPositionMargin(positionMargin);
							// 未实现盈亏
							vo.setFloatProfit(floatProfit);

						} catch (Exception e) {
							vo.setTotal(BigDecimal.ZERO);
							vo.setAvailable(BigDecimal.ZERO);
							vo.setFrozen(BigDecimal.ZERO);
							vo.setPositionMargin(BigDecimal.ZERO);
							vo.setFloatProfit(BigDecimal.ZERO);
						}

						// 发送消息
						entry.getKey().sendMessage(getTextMessage(entry.getValue().getDataList(), vo));
					} catch (Exception ex) {
						ex.printStackTrace();
						log.info("push last price err:" + ex.getMessage());
					}

				}
			} catch (Exception e) {
				e.printStackTrace();
				log.info("push ranking err:" + e.getMessage());
			}

		}, 0, 300, TimeUnit.MILLISECONDS);
	}

	private void sendMessage(Map.Entry<WebSocketSession, AbstractTopicVO> entry) {

	}


}
